package store

import (
	"crypto/sha1"
	"crypto/x509"
	"encoding/hex"
	"fmt"
	"strings"
)

// StoreName 证书存储名称
type StoreName string

const (
	StoreRoot       StoreName = "Root"
	StoreCA         StoreName = "CA"
	StoreDisallowed StoreName = "Disallowed"
)

// Certificate 表示一个证书
type Certificate struct {
	Thumbprint   string    // SHA1 指纹（40位十六进制）
	Subject      string    // 证书主体
	Issuer       string    // 证书颁发者
	SerialNumber string    // 序列号
	RawData      []byte    // 原始证书数据（DER 编码）
	Store        StoreName // 所属存储
}

// Store 表示 Windows 证书存储
type Store struct {
	name StoreName
	impl *storeImpl
}

// FindByThumbprint 根据指纹查找证书
func (s *Store) FindByThumbprint(thumbprint string) (*Certificate, error) {
	thumbprint = normalizeThumbprint(thumbprint)
	return s.impl.findByThumbprint(thumbprint)
}

// Add 添加证书到存储
func (s *Store) Add(cert *Certificate) error {
	return s.impl.add(cert)
}

// Remove 从存储中移除证书
func (s *Store) Remove(thumbprint string) error {
	thumbprint = normalizeThumbprint(thumbprint)
	return s.impl.remove(thumbprint)
}

// List 列出存储中的所有证书
func (s *Store) List() ([]*Certificate, error) {
	return s.impl.list()
}

// Close 关闭证书存储
func (s *Store) Close() error {
	return s.impl.close()
}

// MoveCertificate 将证书从一个存储移动到另一个存储
func MoveCertificate(cert *Certificate, from, to StoreName) error {
	// 打开源存储
	fromStore, err := OpenStore(from)
	if err != nil {
		return fmt.Errorf("打开源存储失败: %w", err)
	}
	defer fromStore.Close()

	// 打开目标存储
	toStore, err := OpenStore(to)
	if err != nil {
		return fmt.Errorf("打开目标存储失败: %w", err)
	}
	defer toStore.Close()

	// 添加到目标存储
	cert.Store = to
	if err := toStore.Add(cert); err != nil {
		return fmt.Errorf("添加到目标存储失败: %w", err)
	}

	// 从源存储删除
	if err := fromStore.Remove(cert.Thumbprint); err != nil {
		return fmt.Errorf("从源存储删除失败: %w", err)
	}

	return nil
}

// ParseCertificate 解析证书数据
func ParseCertificate(data []byte, storeName StoreName) (*Certificate, error) {
	cert, err := x509.ParseCertificate(data)
	if err != nil {
		return nil, fmt.Errorf("解析证书失败: %w", err)
	}

	// 计算 SHA1 指纹
	hash := sha1.Sum(data)
	thumbprint := strings.ToUpper(hex.EncodeToString(hash[:]))

	return &Certificate{
		Thumbprint:   thumbprint,
		Subject:      cert.Subject.String(),
		Issuer:       cert.Issuer.String(),
		SerialNumber: cert.SerialNumber.String(),
		RawData:      data,
		Store:        storeName,
	}, nil
}

// normalizeThumbprint 标准化证书指纹（去空格、转大写）
func normalizeThumbprint(thumbprint string) string {
	thumbprint = strings.ReplaceAll(thumbprint, " ", "")
	thumbprint = strings.ReplaceAll(thumbprint, ":", "")
	thumbprint = strings.ToUpper(thumbprint)
	return thumbprint
}

// ValidateThumbprint 验证证书指纹格式
func ValidateThumbprint(thumbprint string) error {
	thumbprint = normalizeThumbprint(thumbprint)
	if len(thumbprint) != 40 {
		return fmt.Errorf("无效的证书指纹长度: %d (期望 40)", len(thumbprint))
	}

	// 验证是否为十六进制
	for _, c := range thumbprint {
		if !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
			return fmt.Errorf("无效的证书指纹字符: %c (必须是十六进制)", c)
		}
	}

	return nil
}
